package com.maimang.platform.base;

import com.fasterxml.jackson.core.type.TypeReference;
import com.maimang.platform.enums.ResultField;
import com.maimang.platform.enums.Status;
import com.maimang.platform.json.JSONObject;
import com.maimang.platform.tool.ToolJackson;
import com.maimang.platform.tool.ToolThrowable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * 操作消息提醒
 *
 * @author Rocky
 */
public class Result<T> extends JSONObject {
	public static final Logger log = LoggerFactory.getLogger(Result.class);
	private static final long serialVersionUID = 1L;

	public static Result create() {
		return new Result();
	}

	public static Result create(Integer code, String data) {
		Result jo = new Result();
		jo.put(ResultField.code.name(), code);
		jo.put(ResultField.message.name(), data);
		return jo;
	}

	public static Result create(Status status) {
		return create(status.code, status.message);
	}

	public static Result create(String key, Object value) {
		return new Result().add(key, value);
	}

	public static Result create(String json) {
		Result jo = new Result();
		try {
			Map<String, Object> fromJson = ToolJackson.toObject(json, new TypeReference<HashMap<String, Object>>() {
			});
			for (Map.Entry<String, Object> entry : fromJson.entrySet()) {
				jo.put(entry.getKey(), entry.getValue());
			}
		} catch (IOException e) {
			log.error("Result.create 解析 JSON 失败");
			return Result.create(Status.generate_return_error);
		}
		return jo;
	}

	public static Result SUCCESS(Status status) {
		return SUCCESS(status.code, status.message);
	}

	public static <T> Result<T> SUCCESS(T data) {
		final Result result = new Result();
		result.put(ResultField.success.name(), true);
		result.put(ResultField.code.name(), Status.success.code);
		result.put(ResultField.message.name(), Status.success.message);
		result.put(ResultField.data.name(), data);
		return result;
	}

	public static Result SUCCESS(Status status, Exception e) {
		return SUCCESS(status.code, ToolThrowable.stacktrace(e));
	}

	public static Result SUCCESS(String code, String message) {
		return getResult(code, message, true);
	}

	public static Result SUCCESS(Integer code, String message) {
		return getResult(code, message, true);
	}

	/**
	 * 返回失败
	 *
	 * @param status
	 * @return
	 */
	public static Result FAIL(Status status) {
		return FAIL(status.code, status.message);
	}

	public static Result FAIL(Status status, Exception e) {
		return FAIL(status.code, ToolThrowable.stacktrace(e));
	}

	public static Result FAIL(String code, String message) {
		return getResult(code, message, false);
	}

	public static Result FAIL(Integer code, String message) {
		return getResult(code, message, false);
	}

	private static Result getResult(Object code, String message, boolean success) {
		final Result result = new Result();
		result.put(ResultField.success.name(), success);
		result.put(ResultField.code.name(), code);
		result.put(ResultField.message.name(), message);
		return result;
	}

	public Integer getCode() {
		return (Integer) this.getOrDefault(ResultField.code.name(), Status.error.code);
	}

	public String getmessage() {
		return (String) this.getOrDefault(ResultField.message.name(), "");
	}

	@Override
	public Result put(String key, Object value) {
		super.put(key, value);
		return this;
	}

	public Result add(String key, Object value) {
		super.put(key, value);
		return this;
	}

	public String toJson() {
		try {
			return ToolJackson.toJson(this);
		} catch (Exception e) {
			log.error("json 解析失败:");
			return ToolJackson.toJson(FAIL(Status.generate_return_error));
		}
	}
}
